package playout_policy;

import java.util.Collections;
import java.util.LinkedList;
import java.util.Random;
import java.util.Set;

import exceptions.AlreadyOccupiedException;
import exceptions.GameOverException;
import exceptions.IllegalMoveException;
import exceptions.ImpossibleMoveException;
import exceptions.KoViolationException;
import exceptions.SuicideMoveException;

import game.GoBoard;
import game.GoGame;
import game.GoGroup;

public class RandomPolicy extends PlayoutPolicy {

	private long seed;

	public RandomPolicy() {
		this.seed = System.currentTimeMillis();
	}
	
	public GoGame generateMove(GoGame g) throws GameOverException {
		Set<Integer> free_intersections = g.getBoard().getFreeIntersections();
		LinkedList<Integer> free_intersections_list = new LinkedList<Integer>();
		free_intersections_list.addAll(free_intersections);
		Random random = new Random(seed);
		Collections.shuffle(free_intersections_list,random);
		this.seed = random.nextLong();
		
		// Is there a move which do not fill an eye on the board ?
		
		for (int move : free_intersections_list) {
			try {
				GoGame copy = new GoGame(g);
				LinkedList<Integer> neighbours = copy.getBoard().neighbours(move);
				boolean fill_an_eye = true;
				int group_around = -1;
				GoGroup[] groups_by_intersection = copy.getGroupsByIntersection();
				GoGroup first_group = groups_by_intersection[neighbours.getFirst()];
				if (first_group == null || first_group.getColor() != copy.getColorToPlay()) fill_an_eye = false;
				else group_around = first_group.getId();
				for (int n : neighbours) {
					if (groups_by_intersection[n] == null) fill_an_eye = false;
					else if (group_around != groups_by_intersection[n].getId()) fill_an_eye = false;
				}
				copy.move(move);
				if (!fill_an_eye && (copy.getGroupsByIntersection()[move].getLibertiesCount() > 1 || (copy.getGroupsByIntersection()[move].getLibertiesCount() == 1 && copy.getGroupsByIntersection()[move].getSize() == 1)) ) {
					return copy;
				}
			} catch (IllegalMoveException e) {
				// Illegal move ; we don't play it
			} catch (ImpossibleMoveException e) {
				System.err.println("Internal error considering "+g.getBoard().labelPosition(move));
				e.printStackTrace();
				return null;
			} catch (GameOverException e) {
				throw e;
			}
		}

		GoGame copy = new GoGame(g);
		try {
			copy.move(GoBoard.PASSING_MOVE);
		} catch (GameOverException e) {
			throw e;
		} catch (Exception e) {
			System.err.println("Internal error");
			e.printStackTrace();
		}
		return copy;
		
	}

}
